package com.zeei.ems.base.globalTX;

import com.zeei.ems.base.anno.EnableTxManager;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 全局事务注册器
 */
public class TxDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(EnableTxManager.class.getName());
        assert annotationAttributes!=null;
        String pointcut = getPointcut(annotationAttributes);
        int txMethodTimeOut = getTxMethodTimeOut(annotationAttributes);
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(GlobalTransactionConfig.class);
        beanDefinitionBuilder.addPropertyValue("pointcut",pointcut);
        beanDefinitionBuilder.addPropertyValue("txMethodTimeOut",txMethodTimeOut);
        String beanName = StringUtils.uncapitalize(GlobalTransactionConfig.class.getSimpleName());
        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        registry.registerBeanDefinition(beanName,beanDefinition);

    }

    private String getPointcut(Map<String, Object> attributes){
        Set<String> pointcutSet = new HashSet<>();
        String[] pointcutArr = (String[]) attributes.get("pointcut");
        for (String pc : pointcutArr) {
            if(StringUtils.isNotBlank(pc)){
                pointcutSet.add("execution("+pc+" )");
            }
        }
        return StringUtils.join(pointcutSet,"||");
    }

    private int getTxMethodTimeOut(Map<String, Object> attributes){
        return (int) attributes.get("txMethodTimeOut");
    }
}
